package org.wesc.boot.webapi.api.system;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.wesc.boot.common.annotation.ApiEndpoint;
import org.wesc.boot.common.api.R;
import org.wesc.boot.common.utils.PasswordHelper;
import org.wesc.boot.dao.domain.QueryRequest;
import org.wesc.boot.dao.entity.User;
import org.wesc.boot.dao.entity.UserConfig;
import org.wesc.boot.dao.model.UserQueryModel;
import org.wesc.boot.dao.model.UserResultModel;
import org.wesc.boot.service.system.user.UserAdvanceService;
import org.wesc.boot.webapi.base.BaseApi;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Wesley
 */
@Api(tags={"用户接口"})
@Slf4j
@Validated
@RestController
@RequestMapping("/api/user")
public class UserApi extends BaseApi {

    private final UserAdvanceService userAdvanceService;

    @Autowired
    public UserApi(UserAdvanceService userAdvanceService) {
        this.userAdvanceService = userAdvanceService;
    }

    @ApiOperation(value = "获取用户列表")
    @GetMapping
    @RequiresPermissions("user:view")
    public R<Map<String, Object>> userList(QueryRequest queryRequest, UserQueryModel model) {
        Map<String, Object> userMap = getDataTable(userAdvanceService.findUserDetail(model, queryRequest));
        return R.data(userMap);
    }

    @ApiOperation(value = "检查用户名")
    @GetMapping("/check/username")
    public R<Boolean> checkUserName(@NotBlank(message = "{required}") String username) {
        User user = this.userAdvanceService.findByUserName(username);
        return R.data(null == user);
    }

    @ApiOperation(value = "获取用户详情")
    @GetMapping("/{username}")
    public R<User> detail(@NotBlank(message = "{required}") @PathVariable String username) {
        User user = this.userAdvanceService.findByUserName(username);
        return R.data(user);
    }

    @ApiOperation(value = "新增用户")
    @PostMapping
    @RequiresPermissions("user:add")
    @ApiEndpoint(operation = "新增用户", exception = "新增用户失败")
    public R<String> addUser(@Valid UserResultModel userResultModel) {
        try {
            userAdvanceService.createUser(userResultModel);
            return R.success();
        } catch (Exception e) {
            String message = "新增用户失败";
            log.error(message, e);
            return R.fail(message);
        }
    }

    @ApiOperation(value = "修改用户")
    @PutMapping
    @RequiresPermissions("user:update")
    @ApiEndpoint(operation = "修改用户", exception = "修改用户失败")
    public R<String> updateUser(@Valid UserResultModel userResultModel) {
        try {
            this.userAdvanceService.updateUser(userResultModel);
            return R.success();
        } catch (Exception e) {
            String message = "修改用户失败";
            log.error(message, e);
            return R.fail(message);
        }
    }

    @ApiOperation(value = "删除用户")
    @DeleteMapping("/{userIds}")
    @RequiresPermissions("user:delete")
    @ApiEndpoint(operation = "删除用户", exception = "删除用户失败")
    public R<String> deleteUsers(@NotBlank(message = "{required}") @PathVariable String userIds) {
        try {
            String[] ids = userIds.split(StringPool.COMMA);
            this.userAdvanceService.deleteUsers(ids);
            return R.success();
        } catch (Exception e) {
            String message = "删除用户失败";
            log.error(message, e);
            return R.fail(message);
        }
    }

    @ApiOperation(value = "个人中心")
    @PutMapping("/profile")
    public R<String> updateProfile(@Valid User user) {
        try {
            this.userAdvanceService.updateProfile(user);
            return R.success();
        } catch (Exception e) {
            String message = "修改个人信息失败";
            log.error(message, e);
            return R.fail(message);
        }
    }

    @ApiOperation(value = "更新用户头像")
    @PutMapping("avatar")
    public R<String> updateAvatar(
            @NotBlank(message = "{required}") String username,
            @NotBlank(message = "{required}") String avatar) {
        try {
            this.userAdvanceService.updateAvatar(username, avatar);
            return R.success();
        } catch (Exception e) {
            String message = "修改头像失败";
            log.error(message, e);
            return R.fail(message);
        }
    }

    @ApiOperation(value = "更新个性化设置")
    @PutMapping("/config/update")
    public R<String> updateUserConfig(@Valid UserConfig userConfig) {
        try {
            this.userAdvanceService.updateUserConfig(userConfig);
            return R.success();
        } catch (Exception e) {
            String message = "修改个性化配置失败";
            log.error(message, e);
            return R.fail(message);
        }
    }

    @ApiOperation(value = "用户密码校验")
    @GetMapping("/check/password")
    public R<Boolean> checkPassword(
            @NotBlank(message = "{required}") String username,
            @NotBlank(message = "{required}") String password) {
        String encryptPassword = PasswordHelper.encryptPassword(password);
        User user = userAdvanceService.findByUserName(username);
        if (user != null) {
            return R.data(StringUtils.equals(user.getPassword(), encryptPassword));
        } else {
            return R.fail("checkPassword failed", false);
        }
    }

    @ApiOperation(value = "修改用户密码")
    @PutMapping("/password")
    @ApiEndpoint(operation = "修改用户密码", exception = "修改用户密码失败")
    public R<String> updatePassword(
            @NotBlank(message = "{required}") String username,
            @NotBlank(message = "{required}") String password) {
        try {
            userAdvanceService.updatePassword(username, password);
            return R.success();
        } catch (Exception e) {
            String message = "修改密码失败";
            log.error(message, e);
            return R.fail(message);
        }
    }

    @ApiOperation(value = "用户密码重置")
    @PutMapping("/password/reset")
    @RequiresPermissions("user:reset")
    public R<String> resetPassword(@NotBlank(message = "{required}") String userNames) {
        try {
            String[] userNameArr = userNames.split(StringPool.COMMA);
            this.userAdvanceService.resetPassword(userNameArr);
            return R.success();
        } catch (Exception e) {
            String message = "重置用户密码失败";
            log.error(message, e);
            return R.fail(message);
        }
    }

    @ApiOperation(value = "批量查询用户")
    @GetMapping(value = "/queryByIds")
    @RequiresPermissions("user:view")
    public R<List<User>> queryByIds(@RequestParam String userIds) {
        String[] userIdArr = userIds.split(",");
        List<Long> idList = new ArrayList<>();
        for (String id : userIdArr) {
            idList.add(Long.valueOf(id));
        }
        return R.data(this.userAdvanceService.findByUserIds(idList));
    }

    @ApiOperation(value = "导出用户")
    @PostMapping("/excel/export")
    @RequiresPermissions("user:export")
    @ApiEndpoint(operation = "导出用户", exception = "导出用户失败")
    public void exportExcel(QueryRequest queryRequest, UserQueryModel model, HttpServletResponse response) throws IOException {
        response.setContentType("APPLICATION/OCTET-STREAM;charset=UTF-8");
        String sheetName = "用户列表";
        List<UserResultModel> userList = this.userAdvanceService.findUserDetail(model, queryRequest).getRecords();
        EasyExcel.write(response.getOutputStream(), UserResultModel.class).sheet(sheetName).doWrite(userList);
    }

}
